package com.witmore.neutron.ai.web.service.impl;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.witmore.neutron.ai.web.service.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 短信服务实现类
 * Author: 豆子高
 * Date: 2025/12/19
 */
@Slf4j
@Service
public class SmsServiceImpl implements SmsService {

    @Value("${aliyun.sms.accessKeyId:}")
    private String accessKeyId;

    @Value("${aliyun.sms.accessKeySecret:}")
    private String accessKeySecret;

    @Value("${aliyun.sms.signName:}")
    private String signName;

    @Value("${aliyun.sms.templateCode:}")
    private String templateCode;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String SMS_CODE_LOGIN_PREFIX = "sms:code:login:";
    private static final String SMS_CODE_BIND_PHONE_PREFIX = "sms:code:bind_phone:";
    private static final int CODE_EXPIRE_MINUTES = 5;
    private static final int CODE_LENGTH = 4;

    // 场景常量
    public static final String SCENE_LOGIN = "LOGIN";
    public static final String SCENE_BIND_PHONE = "BIND_PHONE";

    @Override
    public boolean sendVerificationCode(String phone) {
        // 默认使用登录场景
        return sendVerificationCode(phone, SCENE_LOGIN);
    }

    @Override
    public boolean sendVerificationCode(String phone, String scene) {
        try {
            // 生成4位数字验证码
            String code = generateCode();

            // 发送短信
            boolean sent = sendSms(phone, code);

            if (sent) {
                // 根据场景选择不同的Redis key前缀
                String keyPrefix = getKeyPrefix(scene);
                String key = keyPrefix + phone;
                redisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
                log.info("验证码发送成功，手机号：{}，场景：{}，验证码：{}", phone, scene, code);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("发送验证码失败，手机号：{}，场景：{}", phone, scene, e);
            return false;
        }
    }

    @Override
    public boolean verifyCode(String phone, String code) {
        // 默认使用登录场景
        return verifyCode(phone, code, SCENE_LOGIN);
    }

    @Override
    public boolean verifyCode(String phone, String code, String scene) {
        if (!StringUtils.hasText(phone) || !StringUtils.hasText(code)) {
            return false;
        }

        String keyPrefix = getKeyPrefix(scene);
        String key = keyPrefix + phone;
        String storedCode = redisTemplate.opsForValue().get(key);

        if (storedCode != null && storedCode.equals(code)) {
            // 验证成功后删除验证码
            redisTemplate.delete(key);
            log.info("验证码验证成功，手机号：{}，场景：{}", phone, scene);
            return true;
        }

        log.warn("验证码验证失败，手机号：{}，场景：{}，输入验证码：{}", phone, scene, code);
        return false;
    }

    /**
     * 根据场景获取Redis key前缀
     */
    private String getKeyPrefix(String scene) {
        if (SCENE_BIND_PHONE.equals(scene)) {
            return SMS_CODE_BIND_PHONE_PREFIX;
        }
        // 默认返回登录场景的前缀
        return SMS_CODE_LOGIN_PREFIX;
    }

    /**
     * 生成验证码
     */
    private String generateCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 发送短信
     */
    private boolean sendSms(String phone, String code) {
        try {
            // 检查必要的配置参数
            if (!StringUtils.hasText(accessKeyId) || !StringUtils.hasText(accessKeySecret) ||
                    !StringUtils.hasText(signName) || !StringUtils.hasText(templateCode)) {
                log.error("阿里云短信配置不完整，无法发送短信，手机号：{}", phone);
                return false;
            }

            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            IAcsClient client = new DefaultAcsClient(profile);

            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(phone);
            request.setSignName(signName);
            request.setTemplateCode(templateCode);
            request.setTemplateParam("{\"code\":\"" + code + "\"}");

            SendSmsResponse response = client.getAcsResponse(request);

            if ("OK".equals(response.getCode())) {
                log.info("短信发送成功，手机号：{}，验证码：{}", phone, code);
                return true;
            } else {
                log.error("短信发送失败，手机号：{}，错误码：{}，错误信息：{}", phone, response.getCode(), response.getMessage());
                return false;
            }
        } catch (Exception e) {
            log.error("发送短信异常，手机号：{}", phone, e);
            return false;
        }
    }
}
